<?php

/**
 * Class YRegionComponent
 */
class YRegionComponent extends CComponent
{
	const TYPE_PROVINCE = 1;

	const TYPE_CITY = 2;

	const TYPE_COUNTY = 3;

	public $table = '{{cities}}';

	public $cacheExpires = 86400;

	public function init()
	{

	}

	/**
	 * @param int $code
	 * @return array
	 */
	public function getProvinceList($code = 0)
	{
		$list = array();
		foreach ($this->getItems($code, self::TYPE_PROVINCE) as $row) {
			$list[$row['code']] = $row['name'];
		}
		return $list;
	}

	/**
	 * @param $code
	 * @return array
	 */
	public function getCityListByProvince($code)
	{
		$list = array();
		foreach ($this->getItems($code, self::TYPE_CITY) as $row) {
			$list[$row['code']] = $row['name'];
		}
		return $list;
	}

	/**
	 * @param $code
	 * @return array
	 */
	public function getCountyListByCity($code)
	{
		$list = array();
		foreach ($this->getItems($code, self::TYPE_COUNTY) as $row) {
			$list[$row['code']] = $row['name'];
		}
		return $list;
	}

	/**
	 * @param null $parent
	 * @param null $type
	 * @return array
	 */
	public function getItems($parent = null, $type = null)
	{
		/** @var CDbConnection $db */
		$db = Yii::app()->getDb()->cache($this->cacheExpires);
		if ($type === null && $parent === null) {
			$command = $db->createCommand()
				->select('*')
				->from($this->table);
		} elseif ($parent === null) {
			$command = $db->createCommand()
				->select('*')
				->from($this->table)
				->where('type=:type', array(':type' => $type));
		} elseif ($type === null) {
			$command = $db->createCommand()
				->select('*')
				->from($this->table)
				->where('parent=:parent', array(':parent' => $parent));
		} else {
			$command = $db->createCommand()
				->select('*')
				->from($this->table)
				->where('parent=:parent AND type = :type', array(':type' => $type, ':parent' => $parent));
		}

		return $command->queryAll();
	}

	/**
	 * @param array $codes
	 * @return array
	 */
	public function getItemsByCodes(array $codes)
	{
		/** @var CDbConnection $db */
		$db = Yii::app()->getDb()->cache($this->cacheExpires);
		return $db->createCommand()
			->select('*')
			->from($this->table)
			->where(array('in', 'code', $codes))
			->queryAll();
	}

	/**
	 * @param $code
	 * @param $parent
	 * @return bool
	 */
	public function exists($code, $parent)
	{
		/** @var CDbConnection $db */
		$db = Yii::app()->getDb()->cache($this->cacheExpires);
		return !!$db->createCommand()
			->select('*')
			->from($this->table)
			->where('code=:code AND parent=:parent', array(':code' => $code, ':parent' => $parent))
			->queryRow();
	}

	/**
	 * @param $code
	 * @return mixed
	 */
	public function getItem($code)
	{
		/** @var CDbConnection $db */
		$db = Yii::app()->getDb()->cache($this->cacheExpires);
		return $db->createCommand()
			->select('*')
			->from($this->table)
			->where('code=:code', array(':code' => $code))
			->queryRow();
	}

	/**
	 * @param $province
	 * @param $city
	 * @param $county
	 * @return array
	 */
	public function getFull($province, $city, $county)
	{
		/** @var CDbConnection $db */
		$db = Yii::app()->getDb()->cache($this->cacheExpires);
		$rows = $db->createCommand()
			->select('*')
			->from($this->table)
			->where(array('in', 'code', array($province, $city, $county)))
			->limit(3)
			->queryAll();
		$full = array();
		foreach (array(self::TYPE_PROVINCE, self::TYPE_CITY, self::TYPE_COUNTY) as $type) {
			foreach ($rows as $i => $row) {
				if ($row['type'] == $type) {
					$full[] = $row['name'];
					unset($row[$i]);
				}
			}
		}
		return $full;
	}

	/**
	 * @param null $parent
	 * @return array
	 */
	public function getChildren($parent = null)
	{
		static $children;
		if (!isset($children)) {
			if (($children = Yii::app()->getCache()->get('city_children')) === false) {
				$children = array();
				foreach ($this->getItems() as $row) {
					$children[$row['parent']][$row['code']] = $row;
				}
				Yii::app()->getCache()->set('city_children', $children);
			}
		}
		return $parent === null ? $children : (isset($children[$parent]) ? $children[$parent] : array());
	}

	/**
	 * @param $code
	 * @return string
	 */
	public function getJson($code)
	{
		$rows = $this->getChildren($code);
		$data = array();
		foreach ($rows as $row) {
			$data[] = array(
				'code' => $row['code'],
				'name' => $row['name'],
			);
		}
		return json_encode(array('regions' => $data));
	}

	/**
	 * @param CActiveRecord $model
	 */
	public function registerScript(CActiveRecord $model)
	{
		if (!$model->hasAttribute('province') || !$model->hasAttribute('city')) {
			return;
		}

		$provinceId = CHtml::activeId($model, 'province');
		$cityId = CHtml::activeId($model, 'city');
		$countyId = CHtml::activeId($model, 'county');
		$baseUrl = Yii::app()->getController()->createUrl('region');
		$js = <<<EOT
var province = $('#{$provinceId}'), city = $('#{$cityId}'), county = $('#{$countyId}');
var baseUrl = '{$baseUrl}';
if (!province.val()) {
	city.prop('disabled', true);
	county.prop('disabled', true);
}
if (!city.val()) {
	county.prop('disabled', true);
}
province.change(function() {
	var parent = $(this).val();

	if (!city.get(0)) {
		return;
	}

	county.prop('disabled', true).val('');
	if (!parent) {
		city.prop('disabled', true).val('');
		return;
	}

	$.get(baseUrl, {parent: parent}, function(data) {
		var i,j,region;
		for (i=1, j=data.regions.length; i<=j; i++) {
			region = data.regions[i-1];
			city.get(0).options[i] = new Option(region['name'],region['code']);
		}
		city.prop('disabled', false)
		city.get(0).length = j+1;
	}, 'json');
});

city.change(function() {
	var parent = $(this).val();
	if (!county.get(0)) {
		return;
	}
	if (!parent) {
		county.prop('disabled', true).val('');
		return;
	}
	$.get(baseUrl, {parent: parent}, function(data) {
		var i,j,region;
		for (i=1, j=data.regions.length; i<=j; i++) {
			region = data.regions[i-1];
			county.get(0).options[i] = new Option(region['name'],region['code']);
		}
		county.prop('disabled', false)
		county.get(0).length = j+1;
	}, 'json');
});
EOT;
		Yii::app()->getClientScript()->registerScript(__CLASS__, $js);
	}
}